package com.libinyn.base.pms.common.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


/**
 * Jackson操作工具类
 * @fileName: JsonUtils.java
 * @author: bin.li01
 * @date: 2017/12/3 15:13 
 * @version: v1.0.0
 */
public class JsonUtils {

    /**
     * Jackson JSON操作对象
     */
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        //解析器支持解析单引号
        OBJECT_MAPPER.configure(Feature.ALLOW_SINGLE_QUOTES, true);
        //解析器支持解析结束符
        OBJECT_MAPPER.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        OBJECT_MAPPER.setSerializationInclusion((JsonInclude.Include.NON_NULL));
    }

    /**
     * object对象转换成json
     *
     * @param object
     * @return String
     * @throws com.fasterxml.jackson.core.JsonProcessingException
     */
    public static String object2Json(Object object) throws JsonProcessingException {
        return OBJECT_MAPPER.writeValueAsString(object);
    }

    /**
     * json对象转换成object
     *
     * @param json
     * @param clazz
     * @param <T>
     * @return T
     * @throws com.fasterxml.jackson.core.JsonParseException
     * @throws com.fasterxml.jackson.databind.JsonMappingException
     * @throws java.io.IOException
     */
    public static <T> T json2Object(String json, Class<T> clazz) throws IOException {
        if (json == null) {
            return null;
        }
        return OBJECT_MAPPER.readValue(json, clazz);
    }

    /**
     * json转换成对象Map集合
     *
     * @param json
     * @param clazz
     * @param <T>
     * @return T
     * @throws com.fasterxml.jackson.core.JsonParseException
     * @throws com.fasterxml.jackson.databind.JsonMappingException
     * @throws java.io.IOException
     */
    public static <T> Map<String, T> json2Map(String json, Class<T> clazz) throws IOException {
        Map<String, Map<String, Object>> map = OBJECT_MAPPER.readValue(json, new TypeReference<Map<String, T>>() {
        });
        Map<String, T> result = new HashMap<String, T>();
        for (Entry<String, Map<String, Object>> entry : map.entrySet()) {
            result.put(entry.getKey(), map2Object(entry.getValue(), clazz));
        }
        return result;
    }

    /**
     * 将json转换成对象list集合
     *
     * @param json
     * @param clazz
     * @param <T>
     * @return List<T>
     * @throws java.io.IOException
     * @throws com.fasterxml.jackson.core.JsonParseException
     * @throws com.fasterxml.jackson.databind.JsonMappingException
     */
    public static <T> List<T> json2List(String json, Class<T> clazz) throws IOException {
        List<Map<String, Object>> list = OBJECT_MAPPER.readValue(json, new TypeReference<List<T>>() {
        });
        List<T> result = new ArrayList<T>();
        for (Map<String, Object> map : list) {
            result.add(map2Object(map, clazz));
        }
        return result;
    }

    /**
     * 将map对象转化成object对象
     *
     * @param map
     * @param clazz
     * @param <T>
     * @return T
     * @throws IllegalArgumentException
     */
    public static <T> T map2Object(Map<String, Object> map, Class<T> clazz) throws IllegalArgumentException {
        return OBJECT_MAPPER.convertValue(map, clazz);
    }

    /**
     * JackSon解析日期处理
     *
     * @param dateFormat
     * @return ObjectMapper
     */
    public static ObjectMapper getJacksonMapper(String dateFormat) {
        if (dateFormat != null) {
            OBJECT_MAPPER.setDateFormat(new SimpleDateFormat(dateFormat));
        }
        return OBJECT_MAPPER;
    }
}
